package com.fw.service.merchanttransactiondata.impl;

import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.fw.service.inboundmessagelog.InboundMessageLogService;
import com.fw.service.merchanttransactiondata.MerchantTransactionDataService;
import com.fw.service.merchanttransactiondata.bean.MerchantTransactionDataBean;
import com.fw.service.persistence.dao.PaymentStatusDAO;
import com.fw.service.persistence.dao.TransactionDAO;
import com.fw.service.persistence.dao.TxHistoryLogDAO;
import com.fw.service.persistence.dto.PaymentStatus;
import com.fw.service.persistence.dto.Transaction;
import com.fw.service.persistence.dto.TxHistoryLog;
import com.fw.util.DateUtils;
import com.fw.util.StringUtils;

public class MerchantTransactionDataServiceImpl implements MerchantTransactionDataService {

    private static Logger log = Logger.getLogger(MerchantTransactionDataServiceImpl.class.getName());

    @Autowired
    private InboundMessageLogService inboundMessageLogService;

    @Autowired
    private TransactionDAO transactionDAO;

    @Autowired
    private PaymentStatusDAO paymentStatusDAO;

    @Autowired
    private TxHistoryLogDAO txHistoryLogDAO;

    @Override
    public MerchantTransactionDataBean createMerchantTransactionData(MerchantTransactionDataBean merchantTransactionDataBean) {
	MerchantTransactionDataBean resultMerchantTransactionDataBean = null;
	try {
	    if (merchantTransactionDataBean != null) {

		Transaction transaction = transactionDAO.findByInvoiceNo(merchantTransactionDataBean.getInvoiceNo());
		if (transaction != null) {
		    throw new Exception("InvoiceNo: " + merchantTransactionDataBean.getInvoiceNo() + " existing in system.");
		}
		// save Transaction
		transaction = new Transaction();
		BeanUtils.copyProperties(merchantTransactionDataBean, transaction, "id");
		PaymentStatus paymentStatus = paymentStatusDAO.findByStatusCode(PaymentStatus.STATUS_CODE_INITIATED);
		if (paymentStatus != null) {
		    Date currentDate = DateUtils.getCurrentDate();
		    transaction.setPaymentStatus(paymentStatus);
		    transaction.setCreateDate(StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE));
		    transaction = transactionDAO.save(transaction);

		    // save TxHistoryLog
		    TxHistoryLog txHistoryLog = new TxHistoryLog();
		    txHistoryLog.setTransactionId(transaction.getId());
		    txHistoryLog.setTransactionStatus(paymentStatus.getStatusCode());
		    txHistoryLog.setDateTime(StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE));
		    txHistoryLog.setOperator(TxHistoryLog.OPERATOR_PAYATALL);
		    txHistoryLog = txHistoryLogDAO.save(txHistoryLog);

		    resultMerchantTransactionDataBean = new MerchantTransactionDataBean();
		    BeanUtils.copyProperties(transaction, resultMerchantTransactionDataBean);
		    resultMerchantTransactionDataBean.setId(transaction.getId());
		    resultMerchantTransactionDataBean.setPaymentStatus(paymentStatus.getStatusCode());
		}
	    }
	} catch (Exception e) {
	    log.error(e, e);
	}
	return resultMerchantTransactionDataBean;
    }

    @Override
    public MerchantTransactionDataBean updateMerchantTransactionData(MerchantTransactionDataBean merchantTransactionDataBean) {
	MerchantTransactionDataBean resultMerchantTransactionDataBean = null;
	try {
	    if (merchantTransactionDataBean != null) {
		Transaction transaction = transactionDAO.findOne(merchantTransactionDataBean.getId());
		if (transaction != null) {
		    BeanUtils.copyProperties(merchantTransactionDataBean, transaction, "id", "invoiceNo");
		    PaymentStatus paymentStatus = paymentStatusDAO.findByStatusCode(merchantTransactionDataBean.getPaymentStatus());
		    if (paymentStatus != null) {
			Date currentDate = DateUtils.getCurrentDate();
			transaction.setPaymentStatus(paymentStatus);
			transaction.setUpdateDate(StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE));
			transaction = transactionDAO.save(transaction);

			// save TxHistoryLog
			TxHistoryLog txHistoryLog = new TxHistoryLog();
			txHistoryLog.setTransactionId(transaction.getId());
			txHistoryLog.setTransactionStatus(paymentStatus.getStatusCode());
			txHistoryLog.setDateTime(StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE));
			txHistoryLog.setOperator(TxHistoryLog.OPERATOR_PAYATALL);
			txHistoryLog = txHistoryLogDAO.save(txHistoryLog);

			resultMerchantTransactionDataBean = new MerchantTransactionDataBean();
			BeanUtils.copyProperties(transaction, resultMerchantTransactionDataBean);
			resultMerchantTransactionDataBean.setId(transaction.getId());
			resultMerchantTransactionDataBean.setPaymentStatus(paymentStatus.getStatusCode());
		    }
		}
	    }
	} catch (Exception e) {
	    log.error(e, e);
	}
	return resultMerchantTransactionDataBean;
    }

    @Override
    public MerchantTransactionDataBean getMerchantTransactionData(Long id) {
	MerchantTransactionDataBean resultMerchantTransactionDataBean = null;
	try {
	    Transaction transaction = transactionDAO.findOne(id);
	    resultMerchantTransactionDataBean = new MerchantTransactionDataBean();
	    BeanUtils.copyProperties(transaction, resultMerchantTransactionDataBean);
	    resultMerchantTransactionDataBean.setId(transaction.getId());
	    PaymentStatus paymentStatus = transaction.getPaymentStatus();
	    if (paymentStatus != null) {
		resultMerchantTransactionDataBean.setPaymentStatus(paymentStatus.getStatusCode());
	    }
	    Long inboundMessageLogId = transaction.getInboundMessageLogId();
	    if (inboundMessageLogId != null) {
		resultMerchantTransactionDataBean.setInboundMessageLogBean(inboundMessageLogService
			.getInboundMessageLog(inboundMessageLogId));
	    }
	} catch (Exception e) {
	    log.error(e, e);
	}
	return resultMerchantTransactionDataBean;
    }

    @Override
    public MerchantTransactionDataBean getMerchantTransactionDataByInvoiceNo(String invoiceNo) {
	MerchantTransactionDataBean resultMerchantTransactionDataBean = null;
	try {
	    Transaction transaction = transactionDAO.findByInvoiceNo(invoiceNo);
	    if (transaction != null) {
		resultMerchantTransactionDataBean = new MerchantTransactionDataBean();
		BeanUtils.copyProperties(transaction, resultMerchantTransactionDataBean);
		resultMerchantTransactionDataBean.setId(transaction.getId());
		PaymentStatus paymentStatus = transaction.getPaymentStatus();
		if (paymentStatus != null) {
		    resultMerchantTransactionDataBean.setPaymentStatus(paymentStatus.getStatusCode());
		}
		Long inboundMessageLogId = transaction.getInboundMessageLogId();
		if (inboundMessageLogId != null) {
		    resultMerchantTransactionDataBean.setInboundMessageLogBean(inboundMessageLogService
			    .getInboundMessageLog(inboundMessageLogId));
		}
	    }
	} catch (Exception e) {
	    log.error(e, e);
	}
	return resultMerchantTransactionDataBean;
    }
}
